package com.xyht.sca_s.student_manage_system.modules.purchaseRequisition.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.deepoove.poi.XWPFTemplate;
import com.deepoove.poi.config.Configure;
import com.deepoove.poi.data.PictureRenderData;
import com.deepoove.poi.data.PictureType;
import com.deepoove.poi.data.Pictures;
import com.deepoove.poi.plugin.table.LoopRowTableRenderPolicy;
import com.deepoove.poi.policy.PictureRenderPolicy;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import com.spire.doc.Document;
import com.spire.doc.FileFormat;
import com.xyht.sca_s.student_manage_system.common.commonReturn.CommonCodeEnum;
import com.xyht.sca_s.student_manage_system.common.commonReturn.CommonResult;
import com.xyht.sca_s.student_manage_system.common.commonReturn.ExceptionCast;
import com.xyht.sca_s.student_manage_system.common.commonReturn.ResponseResult;
import com.xyht.sca_s.student_manage_system.common.util.ApiModelUtil;
import com.xyht.sca_s.student_manage_system.common.util.CacheUtil;
import com.xyht.sca_s.student_manage_system.common.util.TimeUtil;
import com.xyht.sca_s.student_manage_system.modules.common.constant.FileSavePathConstant;
import com.xyht.sca_s.student_manage_system.modules.newTips.myEnum.AppTypeEnum;
import com.xyht.sca_s.student_manage_system.modules.newTips.myEnum.RangeTypeEnum;
import com.xyht.sca_s.student_manage_system.modules.newTips.myEnum.TipsTypeEnum;
import com.xyht.sca_s.student_manage_system.modules.newTips.util.NewTipsUtil;
import com.xyht.sca_s.student_manage_system.modules.purchaseRequisition.entity.*;
import com.xyht.sca_s.student_manage_system.modules.purchaseRequisition.entity.dto.*;
import com.xyht.sca_s.student_manage_system.modules.purchaseRequisition.entity.vo.*;
import com.xyht.sca_s.student_manage_system.modules.purchaseRequisition.mapper.*;
import com.xyht.sca_s.student_manage_system.modules.purchaseRequisition.service.SmsPurchaseRequisitionService;
import com.xyht.sca_s.student_manage_system.modules.stampRegistration.entity.SmsStampRegistrationDetail;
import com.xyht.sca_s.student_manage_system.modules.user.entity.SmsRole;
import com.xyht.sca_s.student_manage_system.modules.user.entity.SmsUser;
import com.xyht.sca_s.student_manage_system.modules.user.mapper.SmsRoleMapper;
import com.xyht.sca_s.student_manage_system.modules.user.mapper.SmsUserMapper;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.PDPageContentStream;
import org.apache.pdfbox.pdmodel.font.PDFont;
import org.apache.pdfbox.pdmodel.font.PDType0Font;
import org.apache.pdfbox.pdmodel.graphics.state.PDExtendedGraphicsState;
import org.apache.poi.hssf.usermodel.*;
import org.apache.poi.ss.usermodel.FillPatternType;
import org.apache.poi.ss.usermodel.IndexedColors;
import org.springframework.beans.BeanUtils;
import org.springframework.core.io.ClassPathResource;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.AsyncResult;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.util.*;
import java.util.concurrent.Future;
import java.util.stream.Collectors;

import static com.xyht.sca_s.student_manage_system.common.util.ParamCheckUtil.isNullOrEmpty;
import static com.xyht.sca_s.student_manage_system.modules.infrastructureProject.constant.InfrastructureIsExportProcessConstant.EXPORT_PROCESS_TRUE;
import static com.xyht.sca_s.student_manage_system.modules.purchaseRequisition.constant.PurchaseRequisitionStatusConstant.*;
import static com.xyht.sca_s.student_manage_system.modules.purchaseRequisition.constant.PurchaseRequisitionTypeConstant.*;
import static com.xyht.sca_s.student_manage_system.modules.purchaseRequisition.constant.RequisitionObjectTypeConstant.REQUISITION_OBJECT_TYPE_PERSON;
import static com.xyht.sca_s.student_manage_system.modules.purchaseRequisition.constant.RequisitionObjectTypeConstant.REQUISITION_OBJECT_TYPE_ROLE;
import static com.xyht.sca_s.student_manage_system.modules.student.constant.StudentInfoCommonConstant.PER_SHEET_NUM;

/**
 * <p>
 * 学院请购单 服务实现类
 * </p>
 *
 * @author XYHT
 * @since 2023-06-05
 */
@Service
public class SmsPurchaseRequisitionServiceImpl extends ServiceImpl<SmsPurchaseRequisitionMapper, SmsPurchaseRequisition> implements SmsPurchaseRequisitionService {
    @Resource
    private FileSavePathConstant fileSavePathConstant;
    @Resource
    private SmsPurchaseRequisitionMapper smsPurchaseRequisitionMapper;
    @Resource
    private SmsPurchaseRequisitionProcessMapper smsPurchaseRequisitionProcessMapper;
    @Resource
    private SmsPurchaseRequisitionDetailMapper smsPurchaseRequisitionDetailMapper;
    @Resource
    private NewTipsUtil newTipsUtil;
    @Resource
    private CacheUtil cacheUtil;
    @Resource
    private SmsPurchaseRequisitionMpjMapper smsPurchaseRequisitionMpjMapper;
    @Resource
    private SmsPurchaseRequisitionGoodsMapper smsPurchaseRequisitionGoodsMapper;
    @Resource
    private SmsPurchaseRequisitionGoodsDetailMapper smsPurchaseRequisitionGoodsDetailMapper;
    @Resource
    private SmsUserMapper smsUserMapper;
    @Resource
    private ApiModelUtil apiModelUtil;
    @Resource
    private SmsRoleMapper smsRoleMapper;


    @Override
    @Transactional
    public ResponseResult addPurchaseRequisition(String userId, SmsPurchaseRequisitionDto addPurchaseRequisitionDto) {
        List<SmsPurchaseRequisitionGoodsDto> goodsListDto = addPurchaseRequisitionDto.getGoodsList();
        if(goodsListDto == null || goodsListDto.size() <1){
            return CommonResult.failed(CommonCodeEnum.INVALID_PARAM);
        }
        for (SmsPurchaseRequisitionGoodsDto goods : goodsListDto) {
            if(isNullOrEmpty(goods.getItemName()) || isNullOrEmpty(goods.getRequisitionQuantity())
                    || isNullOrEmpty(goods.getUnit()) || isNullOrEmpty(goods.getUseTo())){
                return CommonResult.failed(CommonCodeEnum.INVALID_PARAM);
            }
        }
        //判断流程是否存在
        List<SmsPurchaseRequisitionProcess> fillProcessList = smsPurchaseRequisitionProcessMapper.selectList(
                new QueryWrapper<SmsPurchaseRequisitionProcess>()
                .lambda()
                .eq(SmsPurchaseRequisitionProcess::getProcessIsApplicantEdit, true)
                .eq(SmsPurchaseRequisitionProcess::getProcessIsUse, true)
                .orderByAsc(SmsPurchaseRequisitionProcess::getProcessSort));
        if(fillProcessList != null && fillProcessList.size() >0){
            if(addPurchaseRequisitionDto.getProcessList() == null || addPurchaseRequisitionDto.getProcessList().size() < 1){
                return CommonResult.failed(CommonCodeEnum.PURCHASE_REQUISITION_ALLOW_USER_NOT_SETTING);
            }
        }

        //判断申请人是否将全部需要编辑流程填写
        List<SmsPurchaseRequisitionProcess> filterList = fillProcessList
                .stream()
                .filter(process ->{
                    List<String> result = addPurchaseRequisitionDto.getProcessList()
                            .stream()
                            .filter(fillProcess -> fillProcess.getProcessId().equals(process.getId()))
                            .map(SmsPurchaseRequisitionDetailDto::getId)
                            .collect(Collectors.toList());
                    //匹配的去除  未匹配的留下
                    if (result.size() > 0) {
                        return false;
                    } else {
                        return true;
                    }
                }).collect(Collectors.toList());

        if(filterList.size() > 0){
            return CommonResult.failed(CommonCodeEnum.PURCHASE_REQUISITION_ALLOW_PROCESS_NOT_FILL);
        }

        //创建申请表
        SmsPurchaseRequisition addPurchaseRequisition = new SmsPurchaseRequisition();
        addPurchaseRequisition.setAllowStatus(PURCHASE_REQUISITION_STATUS_WAIT_ALLOW);//待审批
        addPurchaseRequisition.setRequestorId(userId);
        smsPurchaseRequisitionMapper.insert(addPurchaseRequisition);
        if(addPurchaseRequisition.getId() == null){
            ExceptionCast.cast(CommonResult.failed(CommonCodeEnum.FAIL));
        }
        String approvalId = addPurchaseRequisition.getId();

        //创建物品表
        for (SmsPurchaseRequisitionGoodsDto goodsDto : goodsListDto) {
            SmsPurchaseRequisitionGoods addPurchaseRequisitionGoods = new SmsPurchaseRequisitionGoods();
            BeanUtils.copyProperties(goodsDto,addPurchaseRequisitionGoods);
            addPurchaseRequisitionGoods.setApplyId(approvalId);
            smsPurchaseRequisitionGoodsMapper.insert(addPurchaseRequisitionGoods);
        }


        //创建审批流程
        List<SmsPurchaseRequisitionProcess> originProcessList = smsPurchaseRequisitionProcessMapper.selectList(
                new QueryWrapper<SmsPurchaseRequisitionProcess>()
                .lambda()
                .eq(SmsPurchaseRequisitionProcess::getProcessIsUse, true)
                .orderByAsc(SmsPurchaseRequisitionProcess::getProcessSort));
        if(originProcessList == null || originProcessList.size() < 1){
            ExceptionCast.cast(CommonResult.failed(CommonCodeEnum.PURCHASE_REQUISITION_PROCESS_NOT_SETTING));
        }
        int sort = 1;
        for (SmsPurchaseRequisitionProcess process : originProcessList) {
            //判断管理员是否配置了流程
            if(!process.getProcessIsApplicantEdit()){
                if(isNullOrEmpty(process.getProcessObjectType()) || isNullOrEmpty(process.getProcessObjectId())){
                    return CommonResult.failed(CommonCodeEnum.PURCHASE_REQUISITION_PROCESS_NOT_SETTING);
                }
            }

            //创建审批流程
            SmsPurchaseRequisitionDetail addPurchaseRequisitionDetail = new SmsPurchaseRequisitionDetail();
            addPurchaseRequisitionDetail.setExamineId(approvalId);
            addPurchaseRequisitionDetail.setProcessIsSign(process.getProcessIsSign());
            addPurchaseRequisitionDetail.setProcessIsStamp(process.getProcessIsStamp());
            addPurchaseRequisitionDetail.setDetailSort(sort++);
            addPurchaseRequisitionDetail.setProcessId(process.getId());
            addPurchaseRequisitionDetail.setProcessName(process.getProcessName());
            addPurchaseRequisitionDetail.setProcessIsApplicantEdit(process.getProcessIsApplicantEdit());
            addPurchaseRequisitionDetail.setDetailAllowStatus(PURCHASE_REQUISITION_STATUS_WAIT_ALLOW);

            //申请人可编辑流程
            if(process.getProcessIsApplicantEdit()){
                List<SmsPurchaseRequisitionDetailDto> filterProcessList = addPurchaseRequisitionDto.getProcessList()
                        .stream()
                        .filter(fillProcess -> fillProcess.getProcessId().equals(process.getId()))
                        .collect(Collectors.toList());
                if(filterProcessList.size() < 1){
                    ExceptionCast.cast(CommonResult.failed(CommonCodeEnum.PURCHASE_REQUISITION_ALLOW_PROCESS_NOT_FILL));
                }
                SmsPurchaseRequisitionDetailDto fillProcessDto = filterProcessList.get(0);
                if(isNullOrEmpty(fillProcessDto.getProcessObjectId())){
                    ExceptionCast.cast(CommonResult.failed(CommonCodeEnum.INVALID_PARAM));
                }
                addPurchaseRequisitionDetail.setProcessObjectId(fillProcessDto.getProcessObjectId());
                addPurchaseRequisitionDetail.setProcessObjectType(REQUISITION_OBJECT_TYPE_PERSON);
            }else {
                addPurchaseRequisitionDetail.setProcessObjectId(process.getProcessObjectId());
                addPurchaseRequisitionDetail.setProcessObjectType(process.getProcessObjectType());
            }
            smsPurchaseRequisitionDetailMapper.insert(addPurchaseRequisitionDetail);
        }


        //消息提醒
        //通知流程第一个节点
        SmsPurchaseRequisitionDetail smsPurchaseRequisitionDetail = smsPurchaseRequisitionDetailMapper.selectOne(
                new QueryWrapper<SmsPurchaseRequisitionDetail>()
                .lambda()
                .eq(SmsPurchaseRequisitionDetail::getExamineId, approvalId)
                .eq(SmsPurchaseRequisitionDetail::getDetailSort, 1)
                .orderByAsc(SmsPurchaseRequisitionDetail::getDetailSort));
        RangeTypeEnum rangeTypeEnum;
        if(smsPurchaseRequisitionDetail.getProcessIsApplicantEdit()){
            rangeTypeEnum = RangeTypeEnum.RANGE_TYPE_ENUM_PERSON;
        }else {
            if (smsPurchaseRequisitionDetail.getProcessObjectType() == REQUISITION_OBJECT_TYPE_PERSON) {
                rangeTypeEnum = RangeTypeEnum.RANGE_TYPE_ENUM_PERSON;
            } else {
                rangeTypeEnum = RangeTypeEnum.RANGE_TYPE_ENUM_ROLE;
            }
        }
        List<String> rangeList = new ArrayList<>();
        rangeList.add(smsPurchaseRequisitionDetail.getProcessObjectId());

        newTipsUtil.addNewTips(TipsTypeEnum.TIPS_TYPE_ENUM_ALLOW,
                userId,
                rangeTypeEnum,
                rangeList,
                AppTypeEnum.APP_TYPE_ENUM_PURCHASE_REQUISITION,
                approvalId,
                smsPurchaseRequisitionDetail.getId());
        return CommonResult.success();
        }

    @Override
    @Transactional
    public ResponseResult cancelPurchaseRequisition(String userId, SmsPurchaseRequisitionCancelDto cancelDto) {
        if(isNullOrEmpty(cancelDto.getExamine_id())){
            return CommonResult.failed(CommonCodeEnum.INVALID_PARAM);
        }
        //查看审批表是否存在且是否为本人
        SmsPurchaseRequisition smsPurchaseRequisition = smsPurchaseRequisitionMapper.selectOne(new QueryWrapper<SmsPurchaseRequisition>()
                .lambda()
                .eq(SmsPurchaseRequisition::getId, cancelDto.getExamine_id())
                .eq(SmsPurchaseRequisition::getRequestorId, userId));
        if(smsPurchaseRequisition == null || isNullOrEmpty(smsPurchaseRequisition.getId())){
            return CommonResult.failed(CommonCodeEnum.PURCHASE_REQUISITION_NOT_EXIST);
        }

        //判断审批状态,如果不是待审批状态 撤销失败
        if(smsPurchaseRequisition.getAllowStatus() != PURCHASE_REQUISITION_STATUS_WAIT_ALLOW){
            return CommonResult.failed(CommonCodeEnum.PURCHASE_REQUISITION_CANCEL_FAIL_ALLOWED);
        }

//        //判断是否在审批中
//        List<SmsPurchaseRequisitionDetail> detailList = smsPurchaseRequisitionDetailMapper.selectList(new QueryWrapper<SmsPurchaseRequisitionDetail>()
//                .lambda()
//                .eq(SmsPurchaseRequisitionDetail::getExamineId, cancelDto.getExamine_id())
//                .eq(SmsPurchaseRequisitionDetail::getDetailAllowStatus, PURCHASE_REQUISITION_STATUS_PASS));
//
//        if(detailList != null && detailList.size() > 0){
//            return CommonResult.failed(CommonCodeEnum.PURCHASE_REQUISITION_CANCEL_FAIL_ALLOWED);
//        }

        //撤回审批
        SmsPurchaseRequisition cancelPurchaseRequisition = new SmsPurchaseRequisition();
        cancelPurchaseRequisition.setId(cancelDto.getExamine_id());
        cancelPurchaseRequisition.setAllowStatus(PURCHASE_REQUISITION_STATUS_CANCEL);
        cancelPurchaseRequisition.setProcessEndTime(new Date());
        smsPurchaseRequisitionMapper.updateById(cancelPurchaseRequisition);
        //修改节点流程
        SmsPurchaseRequisitionDetail cancelPurchaseRequisitionDetail = new SmsPurchaseRequisitionDetail();
        cancelPurchaseRequisitionDetail.setDetailAllowStatus(PURCHASE_REQUISITION_STATUS_CANCEL);
        smsPurchaseRequisitionDetailMapper.update(cancelPurchaseRequisitionDetail,new QueryWrapper<SmsPurchaseRequisitionDetail>()
        .lambda()
        .eq(SmsPurchaseRequisitionDetail::getExamineId,cancelDto.getExamine_id())
        .eq(SmsPurchaseRequisitionDetail::getDetailAllowStatus,PURCHASE_REQUISITION_STATUS_WAIT_ALLOW));
        //消息通知
        newTipsUtil.cancelFinishTips(cancelDto.getExamine_id());
        return CommonResult.success();
    }

    @Override
    @Transactional
    public ResponseResult allowPurchaseRequisition(String userId, SmsPurchaseRequisitionAllowDto allowDto) {
        if(isNullOrEmpty(allowDto.getDetailAllowStatus()) || isNullOrEmpty(allowDto.getDetail_id())
        || isNullOrEmpty(allowDto.getExamine_id())){
            return CommonResult.failed(CommonCodeEnum.INVALID_PARAM);
        }
        List<SmsPurchaseRequisitionGoodsDetailDto> approvalQuantityList = allowDto.getApprovalQuantityList();
        if(approvalQuantityList == null || approvalQuantityList.size() < 1){
            return CommonResult.failed(CommonCodeEnum.INVALID_PARAM);
        }

        //判断审批状态只能为通过或驳回
        if(allowDto.getDetailAllowStatus() != PURCHASE_REQUISITION_STATUS_PASS &&
                allowDto.getDetailAllowStatus() != PURCHASE_REQUISITION_STATUS_DENY){
            return CommonResult.failed(CommonCodeEnum.INVALID_PARAM);
        }
        //判断节点是否为待审批
        SmsPurchaseRequisitionDetail smsPurchaseRequisitionDetail = smsPurchaseRequisitionDetailMapper.selectOne(new QueryWrapper<SmsPurchaseRequisitionDetail>()
                .lambda()
                .eq(SmsPurchaseRequisitionDetail::getExamineId, allowDto.getExamine_id())
                .eq(SmsPurchaseRequisitionDetail::getId, allowDto.getDetail_id())
                .eq(SmsPurchaseRequisitionDetail::getDetailAllowStatus, PURCHASE_REQUISITION_STATUS_WAIT_ALLOW));
        if(smsPurchaseRequisitionDetail == null || isNullOrEmpty(smsPurchaseRequisitionDetail.getId())){
            return CommonResult.failed(CommonCodeEnum.PURCHASE_REQUISITION_ALLOW_FAIL);
        }
        //判断该节点是否本人审批（防止跳节点审批)
        if(smsPurchaseRequisitionDetail.getProcessObjectType() == REQUISITION_OBJECT_TYPE_PERSON){
            if(!smsPurchaseRequisitionDetail.getProcessObjectId().equals(userId)){
                return CommonResult.failed(CommonCodeEnum.PURCHASE_REQUISITION_ALLOW_FAIL);
            }
        }else {
            List<String> roleList = cacheUtil.getRoleList(userId);
            List<String> filterRoleList = roleList.stream().filter(role -> role.equals(smsPurchaseRequisitionDetail.getProcessObjectId())).collect(Collectors.toList());
            if(filterRoleList.size() < 1){
                return CommonResult.failed(CommonCodeEnum.PURCHASE_REQUISITION_ALLOW_FAIL);
            }
        }
        //如果是同一个人再判断上个节点是否完成审批
        if(!smsPurchaseRequisitionDetail.getDetailSort().equals(1)){
            SmsPurchaseRequisitionDetail preDetail = smsPurchaseRequisitionDetailMapper.selectOne(new QueryWrapper<SmsPurchaseRequisitionDetail>()
                    .lambda()
                    .eq(SmsPurchaseRequisitionDetail::getExamineId, allowDto.getExamine_id())
                    .eq(SmsPurchaseRequisitionDetail::getDetailSort, smsPurchaseRequisitionDetail.getDetailSort() - 1));
            if(preDetail !=null && !isNullOrEmpty(preDetail.getId())){
                if(preDetail.getDetailAllowStatus() != PURCHASE_REQUISITION_STATUS_PASS) {
                    return CommonResult.failed(CommonCodeEnum.PURCHASE_REQUISITION_ALLOW_FAIL);
                }
            }
        }

        //判断审批数量
        for (SmsPurchaseRequisitionGoodsDetailDto detailDto : approvalQuantityList) {
            SmsPurchaseRequisitionGoods purchaseRequisitionGoods = smsPurchaseRequisitionGoodsMapper.selectById(detailDto.getGoodsId());
            //不能超过申请数量
            if (purchaseRequisitionGoods.getRequisitionQuantity() < detailDto.getApprovedQuantity()) {
                return CommonResult.failed(CommonCodeEnum.PURCHASE_REQUISITION_QUANTITY_OVER);
            }
            //审批数量不能超过前一个节点审批数量
            if (smsPurchaseRequisitionDetail.getDetailSort() > 1) {
                SmsPurchaseRequisitionDetail preDetail = smsPurchaseRequisitionDetailMapper.selectOne(new QueryWrapper<SmsPurchaseRequisitionDetail>()
                        .lambda()
                        .eq(SmsPurchaseRequisitionDetail::getExamineId, allowDto.getExamine_id())
                        .eq(SmsPurchaseRequisitionDetail::getDetailSort, smsPurchaseRequisitionDetail.getDetailSort() - 1));
                SmsPurchaseRequisitionGoodsDetail purchaseRequisitionGoodsDetail = smsPurchaseRequisitionGoodsDetailMapper.selectOne(
                        new QueryWrapper<SmsPurchaseRequisitionGoodsDetail>()
                                .lambda()
                                .eq(SmsPurchaseRequisitionGoodsDetail::getDetailId, preDetail.getId())
                                .eq(SmsPurchaseRequisitionGoodsDetail::getGoodsId, detailDto.getGoodsId()));
                if (purchaseRequisitionGoodsDetail != null && detailDto.getApprovedQuantity() > purchaseRequisitionGoodsDetail.getApprovedQuantity()) {
                    return CommonResult.failed(CommonCodeEnum.PURCHASE_REQUISITION_QUANTITY_OVER_BEFORE);
                }
            }
        }

        //审批节点修改
        SmsPurchaseRequisitionDetail allowPurchaseRequisitionDetail = new SmsPurchaseRequisitionDetail();
        allowPurchaseRequisitionDetail.setDetailAllowStatus(allowDto.getDetailAllowStatus());
        allowPurchaseRequisitionDetail.setId(allowDto.getDetail_id());
        if(!isNullOrEmpty(allowDto.getDetailAllowOpinion())){
            allowPurchaseRequisitionDetail.setDetailAllowOpinion(allowDto.getDetailAllowOpinion());
        }
        allowPurchaseRequisitionDetail.setDetailAllowUserId(userId);
        allowPurchaseRequisitionDetail.setDetailAllowTime(new Date());
        if(smsPurchaseRequisitionDetail.getProcessIsSign()){
            if(isNullOrEmpty(allowDto.getDetailAllowSign())){
                return CommonResult.failed(CommonCodeEnum.INVALID_PARAM);
            }
            allowPurchaseRequisitionDetail.setDetailAllowSign(allowDto.getDetailAllowSign());
        }
        if(smsPurchaseRequisitionDetail.getProcessIsStamp()){
            if(isNullOrEmpty(allowDto.getDetailAllowStamp())){
                return CommonResult.failed(CommonCodeEnum.INVALID_PARAM);
            }
            allowPurchaseRequisitionDetail.setDetailAllowStamp(allowDto.getDetailAllowStamp());
        }
        smsPurchaseRequisitionDetailMapper.updateById(allowPurchaseRequisitionDetail);


        //创建审批物品数量表
        if(allowDto.getDetailAllowStatus() == PURCHASE_REQUISITION_STATUS_PASS){
            for (SmsPurchaseRequisitionGoodsDetailDto goodsDetailDto : approvalQuantityList) {
                SmsPurchaseRequisitionGoodsDetail addPurchaseRequisitionGoodsDetail = new SmsPurchaseRequisitionGoodsDetail();
                addPurchaseRequisitionGoodsDetail.setDetailId(allowPurchaseRequisitionDetail.getId());
                addPurchaseRequisitionGoodsDetail.setGoodsId(goodsDetailDto.getGoodsId());
                addPurchaseRequisitionGoodsDetail.setApprovedQuantity(goodsDetailDto.getApprovedQuantity());
                smsPurchaseRequisitionGoodsDetailMapper.insert(addPurchaseRequisitionGoodsDetail);
            }
        }else {
            for (SmsPurchaseRequisitionGoodsDetailDto goodsDetailDto : approvalQuantityList) {
                SmsPurchaseRequisitionGoodsDetail addPurchaseRequisitionGoodsDetail = new SmsPurchaseRequisitionGoodsDetail();
                addPurchaseRequisitionGoodsDetail.setDetailId(allowPurchaseRequisitionDetail.getId());
                addPurchaseRequisitionGoodsDetail.setGoodsId(goodsDetailDto.getGoodsId());
                addPurchaseRequisitionGoodsDetail.setApprovedQuantity(0);//不通过默认为0
                smsPurchaseRequisitionGoodsDetailMapper.insert(addPurchaseRequisitionGoodsDetail);
            }
        }


        //判断是否最后一个节点 是否驳回
        boolean is_done = false;
        Integer detailCount = smsPurchaseRequisitionDetailMapper.selectCount(new QueryWrapper<SmsPurchaseRequisitionDetail>()
                .lambda()
                .eq(SmsPurchaseRequisitionDetail::getExamineId,allowDto.getExamine_id()));
        if(detailCount.equals(smsPurchaseRequisitionDetail.getDetailSort()) || allowDto.getDetailAllowStatus() == PURCHASE_REQUISITION_STATUS_DENY){
            is_done = true;
            SmsPurchaseRequisition smsPurchaseRequisition = new SmsPurchaseRequisition();
            smsPurchaseRequisition.setId(allowDto.getExamine_id());
            smsPurchaseRequisition.setAllowStatus(allowDto.getDetailAllowStatus());
            smsPurchaseRequisition.setProcessEndTime(new Date());
            smsPurchaseRequisitionMapper.updateById(smsPurchaseRequisition);
        }

        //节点驳回 重置其余节点状态
        if(allowDto.getDetailAllowStatus() == PURCHASE_REQUISITION_STATUS_DENY){
            SmsPurchaseRequisitionDetail approvalDetail = new SmsPurchaseRequisitionDetail();
            approvalDetail.setDetailAllowStatus(PURCHASE_REQUISITION_STATUS_DENY_FINISH);
            smsPurchaseRequisitionDetailMapper.update(approvalDetail,new QueryWrapper<SmsPurchaseRequisitionDetail>()
                    .lambda()
                    .eq(SmsPurchaseRequisitionDetail::getExamineId,allowDto.getExamine_id())
                    .eq(SmsPurchaseRequisitionDetail::getDetailAllowStatus,PURCHASE_REQUISITION_STATUS_WAIT_ALLOW));
        }
        //消息通知
        if (is_done) {
            boolean result_status = false;
            if (allowDto.getDetailAllowStatus() == PURCHASE_REQUISITION_STATUS_PASS) {
                result_status = true;
            }
            newTipsUtil.allowFinishTips(allowDto.getExamine_id(), userId, result_status);
        } else {
            SmsPurchaseRequisitionDetail nextDetail =
                    smsPurchaseRequisitionDetailMapper.selectOne(new QueryWrapper<SmsPurchaseRequisitionDetail>()
                            .lambda()
                            .eq(SmsPurchaseRequisitionDetail::getExamineId, allowDto.getExamine_id())
                            .eq(SmsPurchaseRequisitionDetail::getDetailSort, smsPurchaseRequisitionDetail.getDetailSort() + 1));
            RangeTypeEnum rangeTypeEnum;
            if(nextDetail.getProcessIsApplicantEdit()){
                rangeTypeEnum = RangeTypeEnum.RANGE_TYPE_ENUM_PERSON;
            }else {
                if (nextDetail.getProcessObjectType() == REQUISITION_OBJECT_TYPE_ROLE) {
                    rangeTypeEnum = RangeTypeEnum.RANGE_TYPE_ENUM_ROLE;
                }else {
                    rangeTypeEnum = RangeTypeEnum.RANGE_TYPE_ENUM_PERSON;
                }
            }
            List<String> rangeIDList = new ArrayList<>();
            rangeIDList.add(nextDetail.getProcessObjectId());
            newTipsUtil.allowContinueTips(allowDto.getExamine_id(),
                    userId,
                    rangeTypeEnum,
                    rangeIDList,nextDetail.getId());
        }
        return CommonResult.success();
    }

    @Override
    public ResponseResult getPurchaseRequisitionDetail(String userId, String examineId) {
        if(isNullOrEmpty(examineId)){
            return CommonResult.failed(CommonCodeEnum.INVALID_PARAM);
        }
        SmsPurchaseRequisition purchaseRequisition = smsPurchaseRequisitionMapper.selectById(examineId);
        if(purchaseRequisition == null || isNullOrEmpty(purchaseRequisition.getId())){
            return CommonResult.failed(CommonCodeEnum.PURCHASE_REQUISITION_NOT_EXIST);
        }
        List<SmsPurchaseRequisitionGoods> goodsList = smsPurchaseRequisitionGoodsMapper.selectList(new QueryWrapper<SmsPurchaseRequisitionGoods>()
                .lambda()
                .eq(SmsPurchaseRequisitionGoods::getApplyId, examineId)
                .orderByAsc(SmsPurchaseRequisitionGoods::getCreateTime));
        if(goodsList == null || goodsList.size() <1){
            return CommonResult.failed(CommonCodeEnum.PURCHASE_REQUISITION_NOT_EXIST);
        }

        SmsPurchaseRequisitionVo smsPurchaseRequisitionVo = new SmsPurchaseRequisitionVo();
        BeanUtils.copyProperties(purchaseRequisition,smsPurchaseRequisitionVo);

        smsPurchaseRequisitionVo.setExamineId(purchaseRequisition.getId());//申请表id
        SmsUser userInfo = cacheUtil.getUserInfo(purchaseRequisition.getRequestorId());
        SmsPurchaseRequisitionUserVo applyUserVo = new SmsPurchaseRequisitionUserVo();
        if(userInfo != null){
            BeanUtils.copyProperties(userInfo,applyUserVo);
        }
        smsPurchaseRequisitionVo.setApplyUserInfo(applyUserVo);//申请人信息

        //物品信息和审批信息
        List<SmsPurchaseRequisitionGoodsVo> goodsVoList = goodsList.stream().map(goods -> {
            SmsPurchaseRequisitionGoodsVo smsPurchaseRequisitionGoodsVo = new SmsPurchaseRequisitionGoodsVo();
            BeanUtils.copyProperties(goods, smsPurchaseRequisitionGoodsVo);//物品信息

                List<SmsPurchaseRequisitionGoodsDetailVo> goodsDetailVos = smsPurchaseRequisitionGoodsDetailMapper.selectList(new QueryWrapper<SmsPurchaseRequisitionGoodsDetail>()
                .lambda()
                .eq(SmsPurchaseRequisitionGoodsDetail::getGoodsId,goods.getId()))
                        .stream()
                        .map(goodsDetail1 ->{
                            SmsPurchaseRequisitionGoodsDetailVo purchaseRequisitionGoodsDetailVo = new SmsPurchaseRequisitionGoodsDetailVo();
                            BeanUtils.copyProperties(goodsDetail1,purchaseRequisitionGoodsDetailVo);
                            return purchaseRequisitionGoodsDetailVo;
                        })
                        .collect(Collectors.toList());
                smsPurchaseRequisitionGoodsVo.setApprovedQuantityList(goodsDetailVos);

            return smsPurchaseRequisitionGoodsVo;
        }).collect(Collectors.toList());
        smsPurchaseRequisitionVo.setGoodsList(goodsVoList);

        List<SmsPurchaseRequisitionDetailVo> detailVos = smsPurchaseRequisitionDetailMapper.selectList(new QueryWrapper<SmsPurchaseRequisitionDetail>()
                .lambda()
                .eq(SmsPurchaseRequisitionDetail::getExamineId, purchaseRequisition.getId())
                .orderByAsc(SmsPurchaseRequisitionDetail::getDetailSort))
                .stream()
                .map(detail -> {
                    //节点信息
                    SmsPurchaseRequisitionDetailVo smsPurchaseRequisitionDetailVo = new SmsPurchaseRequisitionDetailVo();
                    BeanUtils.copyProperties(detail, smsPurchaseRequisitionDetailVo);

                    if (!isNullOrEmpty(smsPurchaseRequisitionDetailVo.getDetailAllowUserId())) {
                        SmsUser allowUserInfo = cacheUtil.getUserInfo(smsPurchaseRequisitionDetailVo.getDetailAllowUserId());
                        SmsPurchaseRequisitionUserVo allowUserInfoVo = new SmsPurchaseRequisitionUserVo();
                        if (allowUserInfo != null) {
                            BeanUtils.copyProperties(allowUserInfo, allowUserInfoVo);
                        }
                        smsPurchaseRequisitionDetailVo.setAllowUserInfo(allowUserInfoVo);
                    }

                    if(detail.getProcessObjectType() == REQUISITION_OBJECT_TYPE_PERSON){
                        SmsUser allowUser = cacheUtil.getUserInfo(detail.getProcessObjectId());
                        if(allowUser != null) {
                            smsPurchaseRequisitionDetailVo.setObjectName(allowUser.getRealName());
                            smsPurchaseRequisitionDetailVo.setObjectPic(allowUser.getUserPic());
                        }
                    }else {
                        SmsRole smsRole = smsRoleMapper.selectById(detail.getProcessObjectId());
                        if(smsRole != null) {
                            smsPurchaseRequisitionDetailVo.setObjectName(smsRole.getRoleName());
                        }
                    }
                    return smsPurchaseRequisitionDetailVo;
                })
                .collect(Collectors.toList());
        smsPurchaseRequisitionVo.setDetailList(detailVos);

        return CommonResult.success(smsPurchaseRequisitionVo);
    }

    @Override
    public ResponseResult getPurchaseRequisitionList(String userId, Integer examine_type, Integer pageNum, Integer pageSize,String search_str) {
        if(isNullOrEmpty(examine_type)){
            return CommonResult.failed(CommonCodeEnum.INVALID_PARAM);
        }

        List<SmsPurchaseRequisitionVo> respList = new ArrayList<>();
        int total = 0;
        //已发起
        if(examine_type == PURCHASE_REQUISITION_TYPE_APPLY){
            Page<SmsPurchaseRequisition> page = new Page<>(pageNum,pageSize);
            QueryWrapper<SmsPurchaseRequisition> queryWrapper = new QueryWrapper<>();
            queryWrapper.lambda()
                    .eq(SmsPurchaseRequisition::getRequestorId,userId)
                    .orderByDesc(SmsPurchaseRequisition::getCreateTime);
            if(!isNullOrEmpty(search_str)) {
                List<String> userIds = smsUserMapper.selectList(new QueryWrapper<SmsUser>()
                        .lambda()
                        .like(SmsUser::getRealName, search_str))
                        .stream()
                        .map(SmsUser::getId).collect(Collectors.toList());
                queryWrapper.lambda().and(i -> {
                    if (userIds.size() > 0) {
                        i.or().in(SmsPurchaseRequisition::getRequestorId, userIds);
                    }
                });
            }
            smsPurchaseRequisitionMapper.selectPage(page,queryWrapper);
            respList = page.getRecords()
                    .stream()
                    .map(smsPurchaseRequisition ->{
                        SmsPurchaseRequisitionVo smsPurchaseRequisitionVo = new SmsPurchaseRequisitionVo();
                        BeanUtils.copyProperties(smsPurchaseRequisition,smsPurchaseRequisitionVo);
                        smsPurchaseRequisitionVo.setExamineId(smsPurchaseRequisition.getId());
                        SmsUser userInfo = cacheUtil.getUserInfo(smsPurchaseRequisition.getRequestorId());
                        SmsPurchaseRequisitionUserVo smsPurchaseRequisitionUserVo = new SmsPurchaseRequisitionUserVo();
                        if(userInfo != null){
                            BeanUtils.copyProperties(userInfo,smsPurchaseRequisitionUserVo);
                        }
                        smsPurchaseRequisitionVo.setApplyUserInfo(smsPurchaseRequisitionUserVo);
                        //物品信息
                        List<SmsPurchaseRequisitionGoodsVo> goodsList = smsPurchaseRequisitionGoodsMapper.selectList(new QueryWrapper<SmsPurchaseRequisitionGoods>()
                                .lambda()
                                .eq(SmsPurchaseRequisitionGoods::getApplyId, smsPurchaseRequisition.getId())
                                .orderByAsc(SmsPurchaseRequisitionGoods::getId)
                                .last("limit 3")).stream().map(goods ->{
                            SmsPurchaseRequisitionGoodsVo smsPurchaseRequisitionGoods = new SmsPurchaseRequisitionGoodsVo();
                            BeanUtils.copyProperties(goods,smsPurchaseRequisitionGoods);
                                    return smsPurchaseRequisitionGoods;
                        }).collect(Collectors.toList());
                        smsPurchaseRequisitionVo.setGoodsList(goodsList);
                        return smsPurchaseRequisitionVo;
            })
                    .collect(Collectors.toList());
            total = (int)page.getTotal();
        }else if(examine_type == PURCHASE_REQUISITION_TYPE_ALLOWED){
            Page<SmsPurchaseRequisitionMpjVo> page = new Page<>(pageNum,pageSize);
            MPJLambdaWrapper<SmsPurchaseRequisitionDetail> mpjLambdaWrapper = new MPJLambdaWrapper<>();
            mpjLambdaWrapper.selectAll(SmsPurchaseRequisitionDetail.class)
                    .selectAll(SmsPurchaseRequisition.class)
                    .selectAs(SmsPurchaseRequisition::getCreateTime,"declarationTime")
                    .selectAs(SmsPurchaseRequisitionDetail::getId,"detailId")
                    .leftJoin(SmsPurchaseRequisition.class,SmsPurchaseRequisition::getId,SmsPurchaseRequisitionDetail::getExamineId)
                    .eq(SmsPurchaseRequisitionDetail::getDetailAllowUserId,userId)
//                    .orderByDesc(SmsPurchaseRequisition::getCreateTime)
                    .orderByDesc(SmsPurchaseRequisitionDetail::getDetailAllowTime);
            mpjLambdaWrapper.and(wrapper ->{
                wrapper.eq(SmsPurchaseRequisitionDetail::getDetailAllowStatus,PURCHASE_REQUISITION_STATUS_PASS)
                        .or()
                        .eq(SmsStampRegistrationDetail::getDetailAllowStatus,PURCHASE_REQUISITION_STATUS_DENY);
            });
            if(!isNullOrEmpty(search_str)) {
                List<String> userIds = smsUserMapper.selectList(new QueryWrapper<SmsUser>()
                        .lambda()
                        .like(SmsUser::getRealName, search_str))
                        .stream()
                        .map(SmsUser::getId).collect(Collectors.toList());
                mpjLambdaWrapper.and(i -> {
                    if (userIds.size() > 0) {
                        i.or().in(SmsPurchaseRequisition::getRequestorId, userIds);
                    }
                });
            }
            smsPurchaseRequisitionMpjMapper.selectJoinPage(page, SmsPurchaseRequisitionMpjVo.class,mpjLambdaWrapper);
            respList = page.getRecords()
                    .stream()
                    .map(smsExamineMPJResp ->{
                        SmsPurchaseRequisitionVo smsPurchaseRequisitionVo = new SmsPurchaseRequisitionVo();
                        BeanUtils.copyProperties(smsExamineMPJResp,smsPurchaseRequisitionVo);
                        smsPurchaseRequisitionVo.setCreateTime(smsExamineMPJResp.getCreateTime());

                        SmsUser applyUserInfo = cacheUtil.getUserInfo(smsExamineMPJResp.getRequestorId());
                        SmsPurchaseRequisitionUserVo applyUserVo = new SmsPurchaseRequisitionUserVo();
                        if(applyUserInfo != null){
                            BeanUtils.copyProperties(applyUserInfo,applyUserVo);
                        }
                        smsPurchaseRequisitionVo.setApplyUserInfo(applyUserVo);

                        SmsUser allowUserInfo = cacheUtil.getUserInfo(smsPurchaseRequisitionVo.getDetailAllowUserId());
                        SmsPurchaseRequisitionUserVo allowUserVo = new SmsPurchaseRequisitionUserVo();
                        if(allowUserInfo != null){
                            BeanUtils.copyProperties(allowUserInfo,allowUserVo);
                        }
                        smsPurchaseRequisitionVo.setAllowUserInfo(allowUserVo);

                        //物品信息
                        List<SmsPurchaseRequisitionGoodsVo> goodsList = smsPurchaseRequisitionGoodsMapper.selectList(new QueryWrapper<SmsPurchaseRequisitionGoods>()
                                .lambda()
                                .eq(SmsPurchaseRequisitionGoods::getApplyId, smsExamineMPJResp.getExamineId())
                                .orderByAsc(SmsPurchaseRequisitionGoods::getId)
                                .last("limit 3")).stream().map(goods ->{
                            SmsPurchaseRequisitionGoodsVo smsPurchaseRequisitionGoods = new SmsPurchaseRequisitionGoodsVo();
                            BeanUtils.copyProperties(goods,smsPurchaseRequisitionGoods);
                            return smsPurchaseRequisitionGoods;
                        }).collect(Collectors.toList());
                        smsPurchaseRequisitionVo.setGoodsList(goodsList);
                        return smsPurchaseRequisitionVo;
                    })
                    .collect(Collectors.toList());
            total = (int)page.getTotal();
        }else if(examine_type == PURCHASE_REQUISITION_TYPE_ALLOW_WAIT_ME){
            List<String> roleList = cacheUtil.getRoleList(userId);//获取所有待审批申请流程节点
            List<SmsPurchaseRequisitionDetail> allDetailList = smsPurchaseRequisitionDetailMapper.selectList(
                    new QueryWrapper<SmsPurchaseRequisitionDetail>()
                            .lambda()
                            .eq(SmsPurchaseRequisitionDetail::getDetailAllowStatus, PURCHASE_REQUISITION_STATUS_WAIT_ALLOW));

            List<SmsPurchaseRequisitionDetail> filterDetailList = allDetailList.stream()
                    .filter(detail -> {
                        if(detail.getProcessIsApplicantEdit()){
                            if (!detail.getProcessObjectId().equals(userId)) {
                                return false;
                            }
                        }else {
                            if (detail.getProcessObjectType() == REQUISITION_OBJECT_TYPE_PERSON) {
                                if (!detail.getProcessObjectId().equals(userId)) {
                                    return false;
                                }
                            } else {
                                List<String> filterRoleList = roleList.stream().filter(role -> role.equals(detail.getProcessObjectId())).collect(Collectors.toList());
                                if (filterRoleList.size() < 1) {
                                    return false;
                                }
                            }
                        }

                        if (detail.getDetailSort().equals(1)) {
                            return true;
                        }
                        //判断上一个流程节点是否完成
                        SmsPurchaseRequisitionDetail preDetail =
                                smsPurchaseRequisitionDetailMapper.selectOne(new QueryWrapper<SmsPurchaseRequisitionDetail>()
                                        .lambda()
                                        .eq(SmsPurchaseRequisitionDetail::getExamineId, detail.getExamineId())
                                        .eq(SmsPurchaseRequisitionDetail::getDetailSort, detail.getDetailSort() - 1)
                                        .eq(SmsPurchaseRequisitionDetail::getDetailAllowStatus, PURCHASE_REQUISITION_STATUS_PASS));
                        if (preDetail == null || isNullOrEmpty(preDetail.getId())) {
                            return false;
                        }
                        return true;
                    })
                    .collect(Collectors.toList());
            if (filterDetailList.size() > 0) {
                List<String> detailIDList = filterDetailList.stream().map(SmsPurchaseRequisitionDetail::getId).collect(Collectors.toList());

                Page<SmsPurchaseRequisitionMpjVo> page = new Page<>(pageNum, pageSize);
                MPJLambdaWrapper<SmsPurchaseRequisitionDetail> mpjLambdaWrapper = new MPJLambdaWrapper<>();
                mpjLambdaWrapper.selectAll(SmsPurchaseRequisitionDetail.class)
                        .selectAll(SmsPurchaseRequisition.class)
                        .selectAs(SmsPurchaseRequisition::getCreateTime, "declarationTime")
                        .selectAs(SmsPurchaseRequisitionDetail::getId, "detailId")
                        .leftJoin(SmsPurchaseRequisition.class, SmsPurchaseRequisition::getId, SmsPurchaseRequisitionDetail::getExamineId)
                        .in(SmsStampRegistrationDetail::getId, detailIDList)
                        .orderByDesc(SmsPurchaseRequisition::getCreateTime)
                        .orderByDesc(SmsPurchaseRequisitionDetail::getDetailAllowTime);

                if(!isNullOrEmpty(search_str)) {
                    List<String> userIds = smsUserMapper.selectList(new QueryWrapper<SmsUser>()
                            .lambda()
                            .like(SmsUser::getRealName, search_str))
                            .stream()
                            .map(SmsUser::getId).collect(Collectors.toList());
                    mpjLambdaWrapper.and(i -> {
                        if (userIds.size() > 0) {
                            i.or().in(SmsPurchaseRequisition::getRequestorId, userIds);
                        }
                    });
                }
                smsPurchaseRequisitionMpjMapper.selectJoinPage(page, SmsPurchaseRequisitionMpjVo.class, mpjLambdaWrapper);

                respList = page.getRecords()
                        .stream()
                        .map(smsExamineMPJResp -> {
                            SmsPurchaseRequisitionVo smsExamineResp = new SmsPurchaseRequisitionVo();
                            BeanUtils.copyProperties(smsExamineMPJResp, smsExamineResp);
                            smsExamineResp.setCreateTime(smsExamineMPJResp.getCreateTime());

                            SmsUser applyUser = cacheUtil.getUserInfo(smsExamineResp.getRequestorId());
                            SmsPurchaseRequisitionUserVo smsExamineUserResp = new SmsPurchaseRequisitionUserVo();
                            if (applyUser != null) {
                                BeanUtils.copyProperties(applyUser, smsExamineUserResp);
                            }
                            smsExamineResp.setApplyUserInfo(smsExamineUserResp);

                            //物品信息
                            List<SmsPurchaseRequisitionGoodsVo> goodsList = smsPurchaseRequisitionGoodsMapper.selectList(new QueryWrapper<SmsPurchaseRequisitionGoods>()
                                    .lambda()
                                    .eq(SmsPurchaseRequisitionGoods::getApplyId, smsExamineMPJResp.getExamineId())
                                    .orderByAsc(SmsPurchaseRequisitionGoods::getId)
                                    .last("limit 3")).stream().map(goods ->{
                                SmsPurchaseRequisitionGoodsVo smsPurchaseRequisitionGoods = new SmsPurchaseRequisitionGoodsVo();
                                BeanUtils.copyProperties(goods,smsPurchaseRequisitionGoods);
                                return smsPurchaseRequisitionGoods;
                            }).collect(Collectors.toList());
                            smsExamineResp.setGoodsList(goodsList);

                            return smsExamineResp;
                        })
                        .collect(Collectors.toList());
                total = (int) page.getTotal();
            }
        }
        return CommonResult.success(respList,total);
    }

    @Override
    public ResponseResult getRequisitionOriginSettingProcess() {
        List<SmsPurchaseRequisitionOriginSettingVo> respList = smsPurchaseRequisitionProcessMapper.selectList(
                new QueryWrapper<SmsPurchaseRequisitionProcess>()
                        .lambda()
                        .eq(SmsPurchaseRequisitionProcess::getProcessIsApplicantEdit, true)
                        .eq(SmsPurchaseRequisitionProcess::getProcessIsUse, true)
                        .orderByAsc(SmsPurchaseRequisitionProcess::getProcessSort))
                .stream()
                .map(process -> {
                    SmsPurchaseRequisitionOriginSettingVo originSettingVo = new SmsPurchaseRequisitionOriginSettingVo();
                    BeanUtils.copyProperties(process, originSettingVo);
                    return originSettingVo;
                        })
                .collect(Collectors.toList());
        return CommonResult.success(respList);
    }

    @Override
    public ResponseResult getAllPurchaseRequisitionList(String userId, Integer allowStatus, String applyName, Integer pageNum, Integer pageSize) {
        Page<SmsPurchaseRequisition> page = new Page<>(pageNum,pageSize);
        QueryWrapper<SmsPurchaseRequisition> smsPurchaseRequisitionQueryWrapper = new QueryWrapper<>();
        if(!isNullOrEmpty(allowStatus)){
            smsPurchaseRequisitionQueryWrapper
                    .lambda()
                    .eq(SmsPurchaseRequisition::getAllowStatus,allowStatus);
        }

        if(!isNullOrEmpty(applyName)){
            List<String> userIds = smsUserMapper.selectList(new QueryWrapper<SmsUser>()
                    .lambda()
                    .like(SmsUser::getRealName, applyName))
                    .stream()
                    .map(SmsUser::getId).collect(Collectors.toList());
            if(userIds.size() > 0) {
                smsPurchaseRequisitionQueryWrapper.lambda().in(SmsPurchaseRequisition::getRequestorId, userIds);
            }
        }
        smsPurchaseRequisitionQueryWrapper.lambda().orderByDesc(SmsPurchaseRequisition::getCreateTime);
        smsPurchaseRequisitionMapper.selectPage(page,smsPurchaseRequisitionQueryWrapper);
        List<SmsPurchaseRequisitionVo> purchaseList = new ArrayList<>();
        purchaseList = page.getRecords()
                .stream().map(purchase ->{
                    SmsPurchaseRequisitionVo smsPurchaseRequisitionVo = new SmsPurchaseRequisitionVo();
                    BeanUtils.copyProperties(purchase,smsPurchaseRequisitionVo);
                    smsPurchaseRequisitionVo.setExamineId(purchase.getId());
                    SmsUser userInfo = cacheUtil.getUserInfo(purchase.getRequestorId());
                    SmsPurchaseRequisitionUserVo smsPurchaseRequisitionUserVo = new SmsPurchaseRequisitionUserVo();
                    if(userInfo != null){
                        BeanUtils.copyProperties(userInfo,smsPurchaseRequisitionUserVo);
                    }
                    smsPurchaseRequisitionVo.setApplyUserInfo(smsPurchaseRequisitionUserVo);
                    //物品信息
                    List<SmsPurchaseRequisitionGoodsVo> goodsList = smsPurchaseRequisitionGoodsMapper.selectList(new QueryWrapper<SmsPurchaseRequisitionGoods>()
                            .lambda()
                            .eq(SmsPurchaseRequisitionGoods::getApplyId, purchase.getId())
                            .orderByAsc(SmsPurchaseRequisitionGoods::getId)
                            .last("limit 3")).stream().map(goods ->{
                        SmsPurchaseRequisitionGoodsVo smsPurchaseRequisitionGoods = new SmsPurchaseRequisitionGoodsVo();
                        BeanUtils.copyProperties(goods,smsPurchaseRequisitionGoods);
                        return smsPurchaseRequisitionGoods;
                    }).collect(Collectors.toList());
                    smsPurchaseRequisitionVo.setGoodsList(goodsList);
                    return smsPurchaseRequisitionVo;
                })
                .collect(Collectors.toList());
        int total = (int)page.getTotal();
        return CommonResult.success(purchaseList,total);
    }

    @Override
    @Async
    public Future<ResponseResult> tableDownload(String apply_id, HttpServletResponse response) {
        SmsPurchaseRequisition smsPurchaseRequisition = smsPurchaseRequisitionMapper.selectById(apply_id);
        if (smsPurchaseRequisition == null || smsPurchaseRequisition.getId() == null) {
            return new AsyncResult<>(CommonResult.failed(CommonCodeEnum.PURCHASE_REQUISITION_NOT_EXIST));
        }
//        if (smsPurchaseRequisition.getAllowStatus() == PURCHASE_REQUISITION_STATUS_WAIT_ALLOW) {
//            return new AsyncResult<>(CommonResult.failed(CommonCodeEnum.PURCHASE_REQUISITION_DOWNLOAD_FAIL));
//        }
        List<SmsPurchaseRequisitionGoods> goodsList = smsPurchaseRequisitionGoodsMapper.selectList(
                new QueryWrapper<SmsPurchaseRequisitionGoods>()
        .lambda()
        .eq(SmsPurchaseRequisitionGoods::getApplyId,smsPurchaseRequisition.getId()));


        String OSName = System.getProperty("os.name");
        String filePath = OSName.toLowerCase().startsWith("win") ?fileSavePathConstant.getFILE_DOWNLOAD_PATH()
                : fileSavePathConstant.getFILE_DOWNLOAD_PATH_LINUX();

        String newFilePath = filePath + apply_id + ".docx";
        String pdfFilePath = filePath + apply_id + ".pdf";

        File pdfFile = new File(pdfFilePath);

//        if (!pdfFile.exists()) {
            try {

                Map<String, Object> map = new HashMap<>();
                List<String> picTagList = new ArrayList<>();
                String createTime = TimeUtil.DateHanZiSimpleFormat(smsPurchaseRequisition.getCreateTime());
                map.put("createTime", createTime);

                //获取初始流程
                List<SmsPurchaseRequisitionProcess> processList = smsPurchaseRequisitionProcessMapper.selectList(
                        new QueryWrapper<SmsPurchaseRequisitionProcess>()
                                .lambda()
                                .orderByAsc(SmsPurchaseRequisitionProcess::getProcessSort));
                if (processList == null || processList.size() < 1) {
                    return new AsyncResult<>(CommonResult.failed(CommonCodeEnum.FAIL));
                }

                //获取申请流程
                List<SmsPurchaseRequisitionDetail> detailList = smsPurchaseRequisitionDetailMapper.selectList(
                        new QueryWrapper<SmsPurchaseRequisitionDetail>()
                                .lambda()
                                .eq(SmsPurchaseRequisitionDetail::getExamineId, apply_id));
                if (detailList != null && detailList.size() > 0) {
                    for (SmsPurchaseRequisitionProcess process : processList) {
                        List<SmsPurchaseRequisitionDetail> filterDetail = detailList
                                .stream()
                                .filter(detail -> detail.getProcessId().equals(process.getId()))
                                .collect(Collectors.toList());
                        if (filterDetail.size() > 0) {
                            SmsPurchaseRequisitionDetail detail = filterDetail.get(0);
                            if (detail.getDetailAllowStatus() == PURCHASE_REQUISITION_STATUS_PASS) {
                                map.put("allowStatus" + process.getProcessSort(), "同意");
                            } else if (detail.getDetailAllowStatus() == PURCHASE_REQUISITION_STATUS_DENY) {
                                map.put("allowStatus" + process.getProcessSort(), "拒绝");
                            } else {
                                map.put("allowStatus" + process.getProcessSort(), "");
                            }

                            map.put("allowOption" + process.getProcessSort(), detail.getDetailAllowOpinion());
                            //审批时间
                            if (isNullOrEmpty(detail.getDetailAllowTime())) {
                                map.put("allowTime" + process.getProcessSort(), "");
                            } else {
                                map.put("allowTime" + process.getProcessSort(), TimeUtil.DateHanZiSimpleFormat(detail.getDetailAllowTime()));
                            }


                            //添加签名
                            if (isNullOrEmpty(detail.getDetailAllowSign())) {
                                map.put("allowSign" + process.getProcessSort() , "");
                            } else {
                                String[] splitStr = detail.getDetailAllowSign().split("=");
                                String fileName = splitStr[splitStr.length - 1];
                                File file = new File(filePath + fileName);
                                if(file.exists()) {
                                    InputStream inputStream = new FileInputStream(file);
                                    PictureRenderData pictures = Pictures.ofStream(inputStream,
                                            PictureType.PNG).size(60, 30).create();

                                    map.put("allowSign" + process.getProcessSort(), pictures);
                                    picTagList.add("allowSign" + process.getProcessSort());
                                }
                            }

                            //添加印章
                            if (isNullOrEmpty(detail.getDetailAllowStamp())) {
                                map.put("allowStamp" + process.getProcessSort() , "");
                            } else {
                                String[] splitStr = detail.getDetailAllowStamp().split("=");
                                String fileName = splitStr[splitStr.length - 1];
                                File file = new File(filePath + fileName);
                                if(file.exists()) {
                                    InputStream inputStream = new FileInputStream(file);
                                    PictureRenderData pictures = Pictures.ofStream(inputStream,
                                            PictureType.PNG).size(60, 30).create();

                                    map.put("allowStamp" + process.getProcessSort(), pictures);
                                    picTagList.add("allowStamp" + process.getProcessSort());
                                }
                            }
                        } else {
                            map.put("allowStatus" + process.getProcessSort() , "");
                            map.put("allowOption" + process.getProcessSort() , "");
                            map.put("allowSign" + process.getProcessSort(), "");
                            map.put("allowStamp" + process.getProcessSort(), "");
                            map.put("allowTime" + process.getProcessSort(), "");

                        }
                    }
                }
                List<SmsPurchaseRequisitionTableResp> tableEntityList = new ArrayList<>();
                for (SmsPurchaseRequisitionGoods goods : goodsList) {
                    SmsPurchaseRequisitionTableResp tableEntity = new SmsPurchaseRequisitionTableResp();
                    tableEntity.setItemName(goods.getItemName());
                    tableEntity.setUnit(goods.getUnit());
                    tableEntity.setRemarks(filterResultNull(goods.getRemarks()));
                    tableEntity.setUseTo(filterResultNull(goods.getUseTo()));
                    tableEntity.setRequisitionQuantity(String.valueOf(goods.getRequisitionQuantity()));
                    if(detailList != null && detailList.size() > 0) {
                        for (SmsPurchaseRequisitionDetail detail : detailList) {
                            SmsPurchaseRequisitionGoodsDetail goodsDetail1 = smsPurchaseRequisitionGoodsDetailMapper.selectOne(new QueryWrapper<SmsPurchaseRequisitionGoodsDetail>()
                                    .lambda()
                                    .eq(SmsPurchaseRequisitionGoodsDetail::getDetailId, detail.getId())
                                    .eq(SmsPurchaseRequisitionGoodsDetail::getGoodsId, goods.getId()));
                            if (goodsDetail1 != null) {
                                switch (detail.getProcessName()) {
                                    case "部门负责人":
                                        tableEntity.setApprovedQuantity1(filterResultNull(String.valueOf(goodsDetail1.getApprovedQuantity())));
                                        break;
                                    case "后勤处":
                                        tableEntity.setApprovedQuantity2(filterResultNull(String.valueOf(goodsDetail1.getApprovedQuantity())));
                                        break;
                                    case "分管院长":
                                        tableEntity.setApprovedQuantity3(filterResultNull(String.valueOf(goodsDetail1.getApprovedQuantity())));
                                        break;
                                    case "院长":
                                        tableEntity.setApprovedQuantity4(filterResultNull(String.valueOf(goodsDetail1.getApprovedQuantity())));
                                        break;
                                }
                            }
                        }
                    }
                    tableEntityList.add(tableEntity);
                }

                if (tableEntityList.size() > 0) {
                    map.put("lists", tableEntityList);
                }


                ClassPathResource resource = new ClassPathResource("applyTemplates/purchaseRequisitionTemplate.docx");
                InputStream is = resource.getInputStream();
                FileOutputStream outputStream = new FileOutputStream(newFilePath);

                XWPFTemplate template = XWPFTemplate.compile(is);
                //配置图片标签
                Configure config = template.getConfig();
                for (String tag:picTagList
                ) {
                    config.customPolicy(tag,new PictureRenderPolicy());
                }

                //配置循环表格
                config.customPolicy("lists", new LoopRowTableRenderPolicy());

                template.render(map);
                template.write(outputStream);

                is.close();
                outputStream.close();
                template.close();

                //word转pdf
                File destOri = new File(newFilePath);
                FileInputStream fileInputStream = new FileInputStream(destOri);
                FileOutputStream fileOutputStream = new FileOutputStream(pdfFilePath);

                Document document = new Document();
                document.loadFromStream(fileInputStream, FileFormat.Docx);
                //保存为PDF
                document.saveToFile(pdfFilePath, FileFormat.PDF);

                fileInputStream.close();
                fileOutputStream.close();
                document.close();

                log.debug("文件生成完成!");
            } catch (Exception e) {
                e.printStackTrace();
                return new AsyncResult<>(CommonResult.failed(CommonCodeEnum.FAIL));
            }
//        }
        try {
            // 加载PDF文档
            PDDocument doc = PDDocument.load(pdfFile);
            doc.setAllSecurityToBeRemoved(true);
            // 创建水印
            String watermark = "南充电影工业职业学院";
            PDPageContentStream contentStream;

            for (PDPage page : doc.getPages()) {
                contentStream = new PDPageContentStream(doc, page, PDPageContentStream.AppendMode.APPEND, true, true);

                //加载字体
                ClassPathResource resource = new ClassPathResource("fonts/123.ttf");
                InputStream is = resource.getInputStream();
                PDFont font = PDType0Font.load(doc, is);


                int startX = 0; // 起始位置 x 坐标
                int startY = 0; // 起始位置 y 坐标
                float angle = -45; // 角度
                float interval = 220; // 间隔
                float opacity = 0.3f; // 透明度
                int colorR = 127; // 颜色 red 值
                int colorG = 127; // 颜色 green 值
                int colorB = 127; // 颜色 blue 值

                //透明的
                PDExtendedGraphicsState r0 = new PDExtendedGraphicsState();
                r0.setNonStrokingAlphaConstant(opacity);
                r0.setAlphaSourceFlag(true);
                contentStream.setGraphicsStateParameters(r0);

                //水印颜色
                contentStream.setNonStrokingColor(colorR, colorG, colorB);
                contentStream.beginText();
                contentStream.setFont(font, 30f);

                int x_times = (int) Math.ceil(page.getMediaBox().getWidth() / interval);
                int y_times = (int) Math.ceil(page.getMediaBox().getHeight() / interval);
                for (int x = startX; x <= x_times; x++) {
                    for (int y = startY; y <= y_times; y++) {
                        contentStream.setTextRotation(angle, (x * interval), (y * interval));
                        contentStream.showText(watermark);
                    }
                }
                contentStream.endText();
                contentStream.restoreGraphicsState();
                contentStream.close();
                is.close();
            }


            response.setCharacterEncoding("utf-8");
            response.setContentType("application/vnd.pdf;charset=utf-8");
            response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode("学院请购单预览.pdf", "utf-8"));
            response.setHeader("file-name", URLEncoder.encode("学院请购单预览.pdf", "utf-8"));
            response.setHeader("file-type", "download");
            response.setHeader("Access-Control-Expose-Headers", "file-type,file-name");

            //刷新缓冲
            response.flushBuffer();
            // 保存PDF文档
            doc.save(response.getOutputStream());
            doc.close();
        } catch (Exception e) {
            e.printStackTrace();
            return new AsyncResult<>(CommonResult.failed(CommonCodeEnum.FAIL));
        }
        return null;
    }

    @Override
    @Async
    public Future<ResponseResult> exportExamineHistoryList(SmsPurchaseRequisitionHistoryReq req, HttpServletResponse response) {
        if(isNullOrEmpty(req.getIsExportProcess())){
            return new AsyncResult<>(CommonResult.failed(CommonCodeEnum.INVALID_PARAM));
        }
        try {
            QueryWrapper<SmsPurchaseRequisition> smsPurchaseRequisitionQueryWrapper = new QueryWrapper<>();
            if(!isNullOrEmpty(req.getExamineId())){
                smsPurchaseRequisitionQueryWrapper
                        .lambda()
                        .eq(SmsPurchaseRequisition::getId,req.getExamineId());
            }
            if (!isNullOrEmpty(req.getAllowStatus())) {
                smsPurchaseRequisitionQueryWrapper
                        .lambda()
                        .eq(SmsPurchaseRequisition::getAllowStatus, req.getAllowStatus());
            }

            if (!isNullOrEmpty(req.getApplyName())) {
                List<String> userIds = smsUserMapper.selectList(new QueryWrapper<SmsUser>()
                        .lambda()
                        .like(SmsUser::getRealName, req.getApplyName()))
                        .stream()
                        .map(SmsUser::getId).collect(Collectors.toList());
                if(userIds.size() > 0) {
                    smsPurchaseRequisitionQueryWrapper.lambda().in(SmsPurchaseRequisition::getRequestorId, userIds);
                }
            }
            smsPurchaseRequisitionQueryWrapper.lambda().orderByDesc(SmsPurchaseRequisition::getCreateTime);
            List<SmsPurchaseRequisition> list = smsPurchaseRequisitionMapper.selectList(smsPurchaseRequisitionQueryWrapper);

            List<String> idList = list
                    .stream()
                    .map(SmsPurchaseRequisition::getId)
                    .collect(Collectors.toList());

            List<SmsPurchaseRequisitionGoodsExportVo> goodsList = smsPurchaseRequisitionGoodsMapper.selectList(new QueryWrapper<SmsPurchaseRequisitionGoods>()
                    .lambda()
                    .in(SmsPurchaseRequisitionGoods::getApplyId, idList)
            .orderByDesc(SmsPurchaseRequisitionGoods::getCreateTime))
                    .stream()
                    .map(goods ->{
                        SmsPurchaseRequisitionGoodsExportVo exportVo = new SmsPurchaseRequisitionGoodsExportVo();
                        BeanUtils.copyProperties(goods,exportVo);

                        List<SmsPurchaseRequisition> filterList = list.stream()
                                .filter(smsPurchaseRequisition -> exportVo.getApplyId().equals(smsPurchaseRequisition.getId())).collect(Collectors.toList());
                        SmsUser smsUser = smsUserMapper.selectById(filterList.get(0).getRequestorId());
                        if(smsUser != null){
                            exportVo.setApplyUser(smsUser.getRealName());
                        }
                        return exportVo;
                    })
                    .collect(Collectors.toList());


            //表头数据
//            String[] header = req.getLimitColumn().toArray(new String[0]);
            double sheetNum;
            //声明一个工作簿
            HSSFWorkbook workbook = new HSSFWorkbook();
            if (goodsList != null && goodsList.size() > 0) {
                sheetNum = Math.ceil((double) goodsList.size() / PER_SHEET_NUM);
                for (int k = 0; k < sheetNum; k++) {
                    //生成一个表格，设置表格名称为"资源导出表"
                    HSSFSheet sheet = workbook.createSheet("学院请购单记录导出表" + (k + 1));

                    //设置表格列宽度为10个字节
                    sheet.setDefaultColumnWidth(12);
                    //创建标题的显示样式
                    HSSFCellStyle headerStyle = workbook.createCellStyle();
                    headerStyle.setFillForegroundColor(IndexedColors.YELLOW.index);
                    headerStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);

                    HSSFFont f = workbook.createFont();
                    f.setFontHeightInPoints((short) 10);//字号
                    f.setBold(true);//加粗
                    headerStyle.setFont(f);
                    //创建第一行表头
                    HSSFRow headrow = sheet.createRow(0);

                    //遍历添加表头
//                    String[] definedHeader = {"申请表id","申请时间","申请人","物品名称","单位","请购数量","用途","备注"};
                    String[] header = req.getLimitColumn().toArray(new String[0]);
                    for (int i = 0; i < header.length + 1; i++) {
                        //创建一个单元格
                        HSSFCell cell = headrow.createCell(i);

                        if (i == 0) {
                            //创建一个内容对象
                            HSSFRichTextString text = new HSSFRichTextString("序号");
                            //将内容对象的文字内容写入到单元格中
                            cell.setCellValue(text);
                            cell.setCellStyle(headerStyle);
                            continue;
                        }
                        //创建一个内容对象
                        String header1 = apiModelUtil.getFieldValueByFieldName(SmsPurchaseRequisitionGoodsExportVo.class, header[i - 1]);
                        HSSFRichTextString text = new HSSFRichTextString(header1);

                        //将内容对象的文字内容写入到单元格中
                        cell.setCellValue(text);
                        cell.setCellStyle(headerStyle);
                    }

                    //判断是否需要添加流程表头
                    if (req.getIsExportProcess() == EXPORT_PROCESS_TRUE) {
                        HSSFCell cell = headrow.createCell(header.length + 1);

                        HSSFRichTextString text = new HSSFRichTextString("审批流程");

                        //将内容对象的文字内容写入到单元格中
                        cell.setCellValue(text);
                        cell.setCellStyle(headerStyle);
                    }

                    int range = PER_SHEET_NUM;
                    if (k + 1 == sheetNum) {
                        range = goodsList.size() - (PER_SHEET_NUM) * k;
                    }
                    for (int i = 0; i < range; i++) {
                        //创建一行
                        HSSFRow row1 = sheet.createRow(i + 1);
                        SmsPurchaseRequisitionGoodsExportVo exportVo = goodsList.get((PER_SHEET_NUM) * k + i);
                        Map map = JSONObject.parseObject(JSON.toJSONString(exportVo), Map.class);
                        row1.createCell(0).setCellValue(new HSSFRichTextString(i + 1 + ""));
                        for (int j = 0; j < header.length; j++) {
                            String rowContent = "";
                            if (map.get(header[j]) instanceof Long) {
                                rowContent = TimeUtil.DateHanZiSimpleTimestamp((long) map.get(header[j]));
                            } else {
                                rowContent = String.valueOf(map.get(header[j]));
                            }
                            row1.createCell(j + 1).setCellValue(new HSSFRichTextString(rowContent));
                            }
//                        row1.createCell(0).setCellValue(new HSSFRichTextString(i + 1 + ""));
//                        row1.createCell(1).setCellValue(new HSSFRichTextString(exportVo.getApplyId()));//申请表id
//                        row1.createCell(2).setCellValue(new HSSFRichTextString(TimeUtil.DateHanZiSimpleFormat(exportVo.getCreateTime())));//申请时间
//                        row1.createCell(3).setCellValue(new HSSFRichTextString(exportVo.getApplyUser()));//申请人
//                        row1.createCell(4).setCellValue(new HSSFRichTextString(exportVo.getItemName()));//物品名称
//                        row1.createCell(5).setCellValue(new HSSFRichTextString(exportVo.getUnit()));//单位
//                        row1.createCell(6).setCellValue(new HSSFRichTextString(String.valueOf(exportVo.getRequisitionQuantity())));//请购数量
//                        row1.createCell(7).setCellValue(new HSSFRichTextString(filterResultNull(exportVo.getUseTo())));//用途
//                        row1.createCell(8).setCellValue(new HSSFRichTextString(filterResultNull(exportVo.getRemarks())));//备注

                        if (req.getIsExportProcess() == EXPORT_PROCESS_TRUE) {

                            List<SmsPurchaseRequisitionDetail> detailList =
                                    smsPurchaseRequisitionDetailMapper.selectList(new QueryWrapper<SmsPurchaseRequisitionDetail>()
                                            .lambda()
                                            .eq(SmsPurchaseRequisitionDetail::getExamineId, exportVo.getApplyId()));
                            StringBuilder stringBuilder = new StringBuilder();
                            if (detailList != null && detailList.size() > 0) {
                                int sort = 1;
                                for (SmsPurchaseRequisitionDetail detail : detailList) {
                                    SmsPurchaseRequisitionGoodsDetail goodsDetail = smsPurchaseRequisitionGoodsDetailMapper.selectOne(new QueryWrapper<SmsPurchaseRequisitionGoodsDetail>()
                                            .lambda()
                                            .eq(SmsPurchaseRequisitionGoodsDetail::getGoodsId, exportVo.getId())
                                            .eq(SmsPurchaseRequisitionGoodsDetail::getDetailId, detail.getId()));
                                    if (detail.getDetailAllowStatus() != PURCHASE_REQUISITION_STATUS_PASS && detail.getDetailAllowStatus() != PURCHASE_REQUISITION_STATUS_DENY) {
                                        sort += 1;
                                        break;
                                    }
                                    stringBuilder.append("审批节点").append(sort).append(":\n");

                                    SmsUser smsUser = smsUserMapper.selectById(detail.getProcessObjectId());
                                    if (smsUser == null) {
                                        stringBuilder.append("审批人：").append("\n");
                                    } else {
                                        stringBuilder.append("审批人：").append(smsUser.getRealName()).append("\n");
                                    }

                                    if (detail.getDetailAllowStatus() == PURCHASE_REQUISITION_STATUS_PASS) {
                                        stringBuilder.append("审批状态：同意").append("\n");
                                    } else {
                                        stringBuilder.append("审批状态：拒绝").append("\n");
                                    }

                                    if (isNullOrEmpty(detail.getDetailAllowOpinion())) {
                                        stringBuilder.append("审批意见：").append("\n");
                                    } else {
                                        stringBuilder.append("审批意见：").append(detail.getDetailAllowOpinion()).append("\n");
                                    }

                                    if (isNullOrEmpty(goodsDetail.getApprovedQuantity())) {
                                        stringBuilder.append("审批数量: ").append("\n");
                                    } else {
                                        stringBuilder.append("审批数量: ").append(goodsDetail.getApprovedQuantity())
                                                .append("\n");
                                    }

                                    if (isNullOrEmpty(detail.getDetailAllowTime())) {
                                        stringBuilder.append("审批时间：").append("\n");
                                    } else {
                                        stringBuilder.append("审批时间：").append(TimeUtil.DateHanZiSimpleFormat(detail.getDetailAllowTime()))
                                                .append("\n").append("\n");
                                    }
                                    sort++;
                                }
                            }
                            row1.createCell(header.length + 1).setCellValue(new HSSFRichTextString(stringBuilder.toString()));
                        }
                    }
                }
            }

//            response.reset();
            response.setContentType("application/vnd.ms-excel;charset=utf-8");
            response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode("学院请购单记录导出表.xlsx", "utf-8"));
            response.setCharacterEncoding("utf-8");
            response.setHeader("file-type", "download");
            response.setHeader("file-name", URLEncoder.encode("学院请购单记录导出表.xlsx", "utf-8"));
            response.setHeader("Access-Control-Expose-Headers", "file-type,file-name");
//            //刷新缓冲
            response.flushBuffer();
            //workbook将Excel写入到response的输出流中，供页面下载
            OutputStream os = response.getOutputStream();
            workbook.write(os);

            workbook.close();
            os.close();
        } catch (Exception e) {
            e.printStackTrace();
            return new AsyncResult<>(CommonResult.failed(CommonCodeEnum.FAIL));
        }
        return null;
    }

    private String filterResultNull(String resultStr) {
        if (resultStr == null || resultStr.equals("null")) {
            return "";
        }
        return resultStr;
    }


}
